home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 284_01 / bios.c < prev    next >
Text File  |  1989-03-11  |  9KB  |  347 lines

  1. /* bios.c - CP/M BIOS simulator                        */
  2. /* This file depends on system configuration:                */
  3. /* The version is for Turbo C on MS-DOS.  Phisical disk support routine */
  4. /* calls NEC disk BIOS and cannot run on other hardwares.        */
  5.  
  6. #include <stdio.h>
  7. #include <fcntl.h>
  8. #include <dos.h>
  9. #include <conio.h>
  10. #include <io.h>
  11. #include "config.h"
  12. #include "bios.h"
  13.  
  14. /* This module logically consists of 5 parts: phisical disk I/O, direct */
  15. /* I/O port simulation, normal (simulated) disk I/O, character I/O, and */
  16. /* common initialize routines.    The first 2 parts are optional, and you */
  17. /* can eliminate the codes when they are not necessary.            */
  18.  
  19. /* ==================================================================== */
  20. /* PART 1: PHISICAL DISK I/O                        */
  21. /* ==================================================================== */
  22.  
  23. #if PHISDISK
  24.  
  25. /* phisical disk I/O functions */
  26.  
  27. /* disk skew table - not included in BIOS, used on phisical disk only    */
  28. char skew [ 26 ] = {
  29.      1,     7, 13, 19,
  30.     25,     5, 11, 17,
  31.     23,     3,  9, 15,
  32.     21,     2,  8, 14,
  33.     20, 26,  6, 12,
  34.     18, 24,  4, 10,
  35.     16, 22
  36. };
  37.  
  38. char   phisflag;        /* use phisical disk I/O */
  39.  
  40. #define PDA    0x92        /* phisical device address: #3 of 8" drives */
  41.  
  42. char phbuffer [ 256 ];        /* phisical I/O buffer */
  43. char * phbuf;            /* top of phisical I/O buffer */
  44.  
  45. x_phinit ()
  46. {
  47.     struct REGPACK regs;
  48.     unsigned address;
  49.  
  50.     phbuf = phbuffer;
  51.     address = ( FP_SEG( phbuf ) << 4 ) + FP_OFF( phbuf );
  52.     if ( address > 0xFF80 ) phbuf += 128;
  53.  
  54.     regs.r_ax = 0x0700 | PDA;
  55.     intr( 0x1B, ®s );
  56.     if ( regs.r_flags & 1 ) return( 1 );
  57.  
  58.     return( 0 );
  59. }
  60.  
  61. x_phrd ( ptr, trk, sec )
  62.     char * ptr;
  63.     int trk, sec;
  64. {
  65.     struct REGPACK regs;
  66.  
  67.     regs.r_ax = 0x1600 | PDA;
  68.     regs.r_bx = 128;
  69.     regs.r_cx = 0x0000 | trk;
  70.     regs.r_dx = 0x0000 | skew[ sec ];
  71.     regs.r_bp = FP_OFF( phbuf );
  72.     regs.r_es = FP_SEG( phbuf );
  73.     intr( 0x1B, ®s );
  74.     memcpy( ptr, phbuf, 128 );
  75.     return( regs.r_flags & 1 );
  76. }
  77.  
  78. x_phwr ( ptr, trk, sec )
  79.     char * ptr;
  80.     int trk, sec;
  81. {
  82.     struct REGPACK regs;
  83.  
  84.     memcpy( phbuf, ptr, 128 );
  85.     regs.r_ax = 0x1500 | PDA;
  86.     regs.r_bx = 128;
  87.     regs.r_cx = 0x0000 | trk;
  88.     regs.r_dx = 0x0000 | skew[ sec ];
  89.     regs.r_bp = FP_OFF( phbuf );
  90.     regs.r_es = FP_SEG( phbuf );
  91.     intr( 0x1B, ®s );
  92.     return( regs.r_flags & 1 );
  93. }
  94.  
  95. #else
  96.  
  97. x_phinit () { return 1; }
  98. /*ARGSUSED*/ x_phrd ( ptr, trk, sec ) char * ptr; int trk, sec; { return 1; }
  99. /*ARGSUSED*/ x_phwr ( ptr, trk, sec ) char * ptr; int trk, sec; { return 1; }
  100.  
  101. #endif /* PHISDISK */
  102.  
  103. /* ==================================================================== */
  104. /* PART 2: DIRECT I/O SIMULATION                    */
  105. /* ==================================================================== */
  106. /* The following lines are used to simulate IN and OUT instruction.    */
  107. /* You can eliminate the codes by undefining INOUT, or can add them to    */
  108. /* run programs which access phisical I/O ports, simulating actions of    */
  109. /* hardware.  If you do, you must supply actual programs modifing func- */
  110. /* tions x_in and x_out also, which just act as your I/O hardware.    */
  111.  
  112. #if INOUT
  113. /* table to define effective I/O ports                    */
  114. #define IN        CANINPUT
  115. #define OT        CANOUTPUT
  116. #define IO        (CANINPUT|CANOUTPUT)
  117. char IoMap [ 256 ] = {
  118.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  119.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  120.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  121.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  122.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  123.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  124.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  125.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  126.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  127.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  128.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  129.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  130.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  131.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  132.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  133.      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  134. };
  135.  
  136. /* virtual I/O */
  137.  
  138. x_in ( a )
  139.     int a;
  140. {
  141.     /* YOU CAN FILL THE CODE HERE */
  142.     return( 0 );
  143. }
  144.  
  145. /*ARGSUSED*/
  146. x_out ( a, n )
  147.     int a, n;
  148. {
  149.     /* YOU CAN FILL THE CODE HERE */
  150. }
  151.  
  152. #endif /* INOUT */
  153.  
  154. /* ==================================================================== */
  155. /* PART 3: NORMAL DISK                            */
  156. /* ==================================================================== */
  157.  
  158. /* open mode to binary read/write                    */
  159. #define OMODES        ( O_RDWR | O_BINARY )
  160.  
  161. /* get (continuous) secter number                    */
  162. #define SECNUM(t,s)    ( ( t - DPB_OFF ) * DPB_SPT + s )
  163.  
  164. int    disk [ NDISKS ];
  165. char * name [ NDISKS ];
  166.  
  167. x_rd ( ptr, drv, trk, sec )
  168.     char * ptr;
  169.     int drv, trk, sec;
  170. {
  171.     switch ( disk[ drv ] ) {
  172.     case EMPTY:
  173.     return( 1 );
  174.     case PHIS:
  175.     return( x_phrd( ptr, trk, sec ) );
  176.     default:
  177.     if ( trk < DPB_OFF ) return( 1 );
  178.     lseek( disk[ drv ], ( long )SECNUM( trk, sec ) * SECLEN, 0 );
  179.     return( read( disk[ drv ], ptr, SECLEN ) < 0 );
  180.     }
  181. }
  182.  
  183. x_wr ( ptr, drv, trk, sec )
  184.     char * ptr;
  185.     int drv, trk, sec;
  186. {
  187.     switch ( disk[ drv ] ) {
  188.     case EMPTY:
  189.     return( 1 );
  190.     case PHIS:
  191.     return( x_phwr( ptr, trk, sec ) );
  192.     default:
  193.     if ( trk < DPB_OFF ) return( 1 );
  194.     lseek( disk[ drv ], ( long )SECNUM( trk, sec ) * SECLEN, 0 );
  195.     return( write( disk[ drv ], ptr, SECLEN ) < SECLEN );
  196.     }
  197. }
  198.  
  199. /* ==================================================================== */
  200. /* PART 4: CHARACTER I/O                        */
  201. /* ==================================================================== */
  202.  
  203. /* pseudo BIOS functions */
  204.  
  205. x_const ()
  206. {
  207.     return( ioctl( 0, 6 ) );
  208. }
  209.  
  210. x_conin ()
  211. {
  212.     return( getch() );
  213. }
  214.  
  215. x_conot ( c )
  216.     char c;
  217. {
  218.     putch( c );
  219. }
  220.  
  221. x_lstot ( c )
  222.     char c;
  223. {
  224.     write( 4, &c, 1 );
  225. }
  226.  
  227. x_lstst ()
  228. {
  229.     return( ioctl( 4, 7 ) );
  230. }
  231.  
  232. x_auxin ()
  233. {
  234.     char c;
  235.  
  236.     if ( read( 3, &c, 1 ) < 1 ) {
  237.     return( 0x1A );
  238.     } else {
  239.     return( c & 0xFF );
  240.     }
  241. }
  242.  
  243. x_auxot ( c )
  244.     char c;
  245. {
  246.     write( 3, &c, 1 );
  247. }
  248.  
  249. /* ==================================================================== */
  250. /* PART 5: INITIALIZE ROUTINES                        */
  251. /* ==================================================================== */
  252.  
  253. int cbrk;            /* old check-break-key mode */
  254. int cimode, comode;        /* old console modes */
  255.  
  256. /* initialize */
  257. x_init ( argc, argv )
  258.     int argc;
  259.     char * argv [];
  260. {
  261.     int i, d;
  262.     char * p;
  263.     extern char * i_sysdsk();
  264.  
  265.     name[ 0 ] = i_sysdsk();
  266.     for ( i = 1; i < NDISKS; i++ ) {
  267.     name[ i ] = NULL;
  268.     }
  269.  
  270.     for ( i = 0; i < argc; i++ ) {
  271.     p = argv[ i ];
  272.     if ( p[ 0 ] == '-' && p[ 1 ] >= 'A' && p[ 1 ] < 'A' + NDISKS ) {
  273.         name[ p[ 1 ] - 'A' ] = argv[ i + 1 ];
  274.     }
  275.     }
  276.  
  277. #if PHISDISK
  278.     phisflag = 0;
  279. #endif
  280.  
  281.     for ( i = 0; i < NDISKS; i++ ) {
  282.     if ( name[ i ] == NULL ) {
  283.         d = EMPTY;
  284.     } else if ( strcmp( name[ i ], "." ) == 0 ) {
  285. #if PHISDISK
  286.         if ( phisflag ) {
  287.         fputs( "Only one phisical drive is allowed\n", stderr );
  288.         return( 1 );
  289.         } else {
  290.         d = PHIS;
  291.         phisflag = 1;
  292.         }
  293. #else
  294.         fputs( "phisical drive is not supported\n", stderr );
  295.         return( 1 );
  296. #endif
  297.     } else {
  298.         d = open( name[ i ], OMODES );
  299.         if ( d < 0 ) {
  300.         fputs( "Cannot open ", stderr );
  301.         fputs( name[ i ], stderr );
  302.         fputs( "\n", stderr );
  303.         return( 1 );
  304.         }
  305.     }
  306.     disk[ i ] = d;
  307.     }
  308.  
  309. #if PHISDISK
  310.     if ( phisflag ) {
  311.     if ( x_phinit() ) {
  312.         fputs( "Cannot use phisical drive\n", stderr );
  313.         return( 1 );
  314.     }
  315.     }
  316. #endif
  317.  
  318.     setmode( 0, O_BINARY );
  319.     setmode( 1, O_BINARY );
  320.     cimode = ioctl( 0, 0 );
  321.     if ( cimode >= 0 && ( cimode & 0x0080 ) ) {
  322.     ioctl( 0, 1, cimode & 0x00FF | 0x0060 );
  323.     }
  324.     comode = ioctl( 1, 0 );
  325.     if ( comode >= 0 && ( comode & 0x0080 ) ) {
  326.     ioctl( 1, 1, comode & 0x00FF | 0x0020 );
  327.     }
  328.     cbrk = getcbrk();
  329.     setcbrk( 0 );
  330.  
  331.     return( 0 );
  332. }
  333.